<?php


namespace app\http;


class Http
{

    static public $way = 0;

    // 手动设置访问方式
    static public function setWay($way)
    {
        self:: $way = intval($way);
    }

    static public function getSupport()
    {
        // 如果指定访问方式，则按指定的方式去访问
        if (isset(self:: $way) && in_array(self:: $way, array(1, 2, 3)))
            return self:: $way;
        // 自动获取最佳访问方式
        if (function_exists('curl_init')) { // curl方式
            return 1;
        } else if (function_exists('fsockopen')) { // socket
            return 2;
        } else if (function_exists('file_get_contents')) { // php系统函数file_get_contents
            return 3;
        } else {
            return 0;
        }
    }

    // 通过socket get数据
    static public function socketGet($url, $timeout = 5, $header = "")
    {
        $header = empty($header) ? self:: defaultHeader() : $header;
        $url2 = parse_url($url);
        $url2["path"] = isset($url2["path"]) ? $url2["path"] : "/";
        $url2["port"] = isset($url2["port"]) ? $url2["port"] : 80;
        $url2["query"] = isset($url2["query"]) ? "?" . $url2["query"] : "";
        $host_ip = @gethostbyname($url2["host"]);

        if (($fsock = fsockopen($host_ip, $url2['port'], $errno, $errstr, $timeout)) < 0) {
            return false;
        }
        $request = $url2["path"] . $url2["query"];
        $in = "GET " . $request . " HTTP/1.0\r\n";
        if (false === strpos($header, "Host:")) {
            $in .= "Host: " . $url2["host"] . "\r\n";
        }
        $in .= $header;
        $in .= "Connection: Close\r\n\r\n";

        if (!@fwrite($fsock, $in, strlen($in))) {
            @fclose($fsock);
            return false;
        }
        return self:: GetHttpContent($fsock);
    }

    // 获取通过socket方式get和post页面的返回数据
    static private function GetHttpContent($fsock = null)
    {
        $out = null;
        while ($buff = @fgets($fsock, 2048)) {
            $out .= $buff;
        }
        fclose($fsock);
        $pos = strpos($out, "\r\n\r\n");
        $head = substr($out, 0, $pos); //http head
        $status = substr($head, 0, strpos($head, "\r\n")); //http status line
        $body = substr($out, $pos + 4, strlen($out) - ($pos + 4)); //page body
        if (preg_match("/^HTTP\/\d\.\d\s([\d]+)\s.*$/", $status, $matches)) {
            if (intval($matches[1]) / 100 == 2) {
                return $body;
            } else {
                return false;
            }
        } else {
            return false;
        }
    }

    // 通过POST方式发送数据
    public static function doPost($url, $post_data = array(), $timeout = 5, $header = "")
    {
        if (empty($url) || empty($post_data) || empty($timeout))
            return false;
        if (!preg_match('/^(http|https)/is', $url))
            $url = "http://" . $url;

        $code = self:: getSupport();
        switch ($code) {
            case 1:
                return self:: curlPost($url, $post_data, $timeout, $header);
                break;
            case 2:
                return self:: socketPost($url, $post_data, $timeout, $header);
                break;
            case 3:
                return self:: phpPost($url, $post_data, $timeout, $header);
                break;
            default:
                return false;
        }
    }

    // 通过file_get_contents 函数post数据
    static public function phpPost($url, $post_data = array(), $timeout = 5, $header = "")
    {
        $header = empty($header) ? self:: defaultHeader() : $header;
        $post_string = http_build_query($post_data);
        $header .= "Content-length: " . strlen($post_string);
        $opts = array('http' => array(
            'protocol_version' => '1.0', // http协议版本(若不指定php5.2系默认为http1.0)
            'method' => "POST", // 获取方式
            'timeout' => $timeout, // 超时时间
            'header' => $header,
            'content' => $post_string)
        );
        $context = stream_context_create($opts);
        return @file_get_contents($url, false, $context);
    }

    // 通过socket post数据
    static public function socketPost($url, $post_data = array(), $timeout = 5, $header = "")
    {
        $header = empty($header) ? self:: defaultHeader() : $header;
        $post_string = http_build_query($post_data);

        $url2 = parse_url($url);
        $url2["path"] = ($url2["path"] == "" ? "/" : $url2["path"]);
        $url2["port"] = ($url2["port"] == "" ? 80 : $url2["port"]);
        $host_ip = @gethostbyname($url2["host"]);
        $fsock_timeout = $timeout; //超时时间
        if (($fsock = fsockopen($host_ip, $url2['port'], $errno, $errstr, $fsock_timeout)) < 0) {
            return false;
        }
        $request = $url2["path"] . ($url2["query"] ? "?" . $url2["query"] : "");
        $in = "POST " . $request . " HTTP/1.0\r\n";
        $in .= "Host: " . $url2["host"] . "\r\n";
        $in .= $header;
        $in .= "Content-type: application/x-www-form-urlencoded\r\n";
        $in .= "Content-Length: " . strlen($post_string) . "\r\n";
        $in .= "Connection: Close\r\n\r\n";
        $in .= $post_string . "\r\n\r\n";
        unset($post_string);
        if (!@fwrite($fsock, $in, strlen($in))) {
            @fclose($fsock);
            return false;
        }
        return self:: GetHttpContent($fsock);
    }

    // 通过curl get数据
    public static function curlGet($url, $timeout = 5, $header = "")
    {
        $header = empty($header) ? self:: defaultHeader() : $header;
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
        curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
        curl_setopt($ch, CURLOPT_HTTPHEADER, array($header)); //模拟的header头
        $result = curl_exec($ch);
        curl_close($ch);
        return $result;
    }

    // 通过curl post数据
    public static function curlPost($url, $post_data = array(), $timeout = 5, $header = "")
    {
        $header = empty($header) ? '' : $header;
        $post_string = http_build_query($post_data);
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $post_string);
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
        curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
        curl_setopt($ch, CURLOPT_HTTPHEADER, array($header)); //模拟的header头
        $result = curl_exec($ch);
        curl_close($ch);

        return $result;
    }

    // 通过curl post数据
    static public function curlPost1($url, $post_data = array(), $timeout = 5, $header = "")
    {
        $header = empty($header) ? '' : $header;
        $post_string = http_build_query($post_data);
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $post_string);
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
        curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
        curl_setopt($ch, CURLOPT_HTTPHEADER, array($header)); //模拟的header头
        $result = curl_exec($ch);
        curl_close($ch);
        return $result;
    }

    // 通过curl post数据
    public static function curlPostJson($url, $data = array(), $timeout = 5, $header = "")
    {

        $curl = curl_init();

        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
        if(!$data){
            return 'data is null';
        }
        if(is_array($data))
        {
            $data = json_encode($data);
        }
        print_r($data);
        curl_setopt($curl, CURLOPT_POST, 1);
        curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
        curl_setopt($curl, CURLOPT_HEADER, 0);
        curl_setopt($curl, CURLOPT_HTTPHEADER,array(
            'Content-Type: application/json; charset=utf-8',
            'Content-Length:' . strlen($data),
            'Cache-Control: no-cache',
            'Pragma: no-cache'
        ));
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        $res = curl_exec($curl);
        $errorno = curl_errno($curl);
        if ($errorno) {
            return $errorno;
        }
        curl_close($curl);
        return $res;
    }

    // 默认模拟的header头
    private static function defaultHeader()
    {
        $header = "User-Agent:Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12\r\n";
        $header .= "Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";
        $header .= "Accept-language: zh-cn,zh;q=0.5\r\n";
        $header .= "Accept-Charset: GB2312,utf-8;q=0.7,*;q=0.7\r\n";
        return $header;
    }
}